
const rooms = {
  '': { roomPwd: '', groupChat: 0 }
}

module.exports = function(server){
  const io = require('socket.io')(server, {
    path: '/im',
    serveClient: false,
    pingInterval: 10000,
    pingTimeout: 5000,
    cookie: false,
  })

  io.use(async function(socket, next) {
    let { action, nickname, roomNo, roomPwd, groupChat=0 } = socket.handshake.query
    groupChat = parseInt(groupChat)
    socket.handshake.query.groupChat = groupChat

    if(!action || !roomNo ||!roomPwd) return next(createError('PARAMS_ERR', '缺少参数'))

    console.log('handshake', socket.handshake.query)

    
    if(action == 'create'){//创建房间
      if(rooms[roomNo]) return next(createError('ROOM_EXISTS', '该房间已存在'))

      rooms[roomNo] = { roomPwd, groupChat }
    }else if(action == 'join'){//加入房间
      let roomData = rooms[roomNo]
      if(!roomData) return next(createError('NO_ROOM', '该房间号不存在'))

      if(roomPwd != roomData.roomPwd){
        return next(createError('NOT_AUTH', '密码错误'))
      }

      let clients = await getRoomClients(io, roomNo)
      if(!roomData.groupChat && clients.length > 1) return next(createError('JOIN_ERR', '该房间不可加入'))
    }

    next()
  })

  io.on('connection', (socket) => {
    //获取房间号
    let { action, nickname, roomNo } = socket.handshake.query

    socket.join(roomNo, () => {
      io.to(roomNo).emit('msg', {
        user: socket.id,
        content: `[${nickname}]已进入对话`,
      })

      socket.emit('msg', {
        user: 'system',
        content: action == 'create'? '等待其他人加入房间' : '你已加入房间，现在开始对话吧',
      })
    })

    //广播到房间
    socket.on('msg', async (data)=>{
      let { roomNo, nickname } = socket.handshake.query
      data.user = socket.id
      data.nickname = nickname
      io.to(roomNo).emit('msg', data)

      let clients = await getRoomClients(io, roomNo)
      if(clients.length == 1){
        socket.emit('msg', {
          user: 'system',
          content: '房间内无其他人，无法发送消息',
        })
      }
    })

    socket.on('disconnect', async (reason) => {
      let { roomNo, nickname } = socket.handshake.query
      io.to(roomNo).emit('msg', {
        user: socket.id,
        content: `[${nickname}]离开房间`,
      })

      let clients = await getRoomClients(io, roomNo)
      if(clients && !clients.length){//所有人离开
        console.log(`delete room ${roomNo}`)
        delete rooms[roomNo]
      }

    })
  })
}

function getRoomClients(io, roomNo){
  return new Promise((resolve, reject)=>{
    io.in(roomNo).clients((err, clients)=>{
      if(err)console.log('get room err', err)

      if(err) return resolve([])
      return resolve(clients)
    })
  })
}

function createError(code, msg){
  return new Error(JSON.stringify({ code, msg }))
}

function getRandomName(len){
  len = len||2
  let str = ''
  while(len-->0) str += String.fromCharCode(parseInt(Math.random()*26)+65)
  return str
}